package com.loooooo.pm2024.modules.pm.controller;


import com.loooooo.pm2024.data.Result;
import com.loooooo.pm2024.modules.pm.model.Issue;
import com.loooooo.pm2024.modules.pm.model.Task;
import com.loooooo.pm2024.modules.pm.selector.IssueSelector;
import com.loooooo.pm2024.modules.pm.service.IssueService;
import com.loooooo.pm2024.modules.res.selector.FileInfoSelector;
import com.loooooo.pm2024.modules.sys.model.DictCatalog;
import com.loooooo.pm2024.modules.sys.selector.DictCatalogSelector;
import com.loooooo.pm2024.modules.sys.service.DictCatalogService;
import com.loooooo.pm2024.security.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Controller
@RequestMapping("/pm/issue")
public class IssueController {
    @Autowired
    IssueService issueService;
    @Autowired
    DictCatalogService catalogService;

    @RequestMapping("/edit")
    String edit(@RequestParam(value = "id", required = false) Long id) {
        return "pm/pm.issue.edit";
    }

    @RequestMapping("/get")
    String get(@RequestParam(value = "id", required = false) Long id) {
        return "pm/pm.issue.get";
    }

    @PostMapping(value = "/get", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    Result get(@RequestParam(value = "id") Long id, @RequestBody(required = false) IssueSelector selector) {

        DictCatalogSelector catalogSelector = new DictCatalogSelector();
        catalogSelector.getTarget().setCode("issue.status");
        catalogSelector.setWithDictList(1);
        List<DictCatalog> catalogList = catalogService.list(catalogSelector);
        return Result.success(issueService.get(id, selector)).set("dict", catalogList).set("now", System.currentTimeMillis());

    }

    @RequestMapping("/list")
    String listGet() {
        return "pm/pm.issue.list";
    }

    @PostMapping(value = "/list", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    Result listPost(@RequestBody(required = false) IssueSelector selector) {
        if (selector == null) selector = new IssueSelector();
        if (!StringUtils.hasText(selector.getOrderBy())) {
            selector.setOrderBy("smart");
        }


        DictCatalogSelector catalogSelector = new DictCatalogSelector();
        catalogSelector.setCodeList(Arrays.asList("issue.status", "issue.urgent", "issue.type"));//.getTarget().setCode("issue.status");
        catalogSelector.setWithDictList(1);
        List<DictCatalog> catalogList = catalogService.list(catalogSelector);
        if (selector.getPageSize() != null) {
            if (selector.getPageNo() == null || selector.getPageNo() < 1) {
                selector.setPageNo(1);
            }
            Result result = new Result();
            int count = issueService.count(selector);
            result.set("total", count);
            if (count > (selector.getPageSize() * (selector.getPageNo() - 1))) {
                result.setData(issueService.list(selector));
            }
            result.set("dict", catalogList);
            return result.set("now", System.currentTimeMillis()).set("loginedUser", SecurityUtils.loginedUser());
        }
        return Result.success(issueService.list(selector)).set("dict", catalogList).set("now", System.currentTimeMillis());

    }

    @PostMapping(value = "/update", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    Result update(@RequestBody Issue issue, @RequestParam(value = "publish", required = false) Integer publish,
                  @RequestParam(value = "assignTo", required = false) Long assignTo,
                  @RequestParam(value = "toList", required = false) String toLists) {
        List<Long> toList = new ArrayList<>();
        if (StringUtils.hasText(toLists)) {
            String[] ss = toLists.split(",");
            for (String s : ss) {
                toList.add(Long.parseLong(s));
            }
        }

        if (assignTo != null) {
            toList.add(assignTo);
        }
        if (toList != null) toList = toList.stream().distinct().collect(Collectors.toList());
        int r = issueService.update(issue, publish, toList);
        return Result.success(issue).set("affect", r).set("now", System.currentTimeMillis());

    }

    @PostMapping(value = "/update/multi", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    Result update(@RequestBody List<Issue> issue) {
        int r = issueService.updateMulti(issue);
        return Result.success(issue).set("affect", r).set("now", System.currentTimeMillis());

    }

    @PostMapping(value = "/assign", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    Result assign(@RequestParam(value = "id") Long issueId,
                  @RequestParam(value = "assignTo", required = false) Long assignTo,
                  @RequestParam(value = "toList", required = false) String toLists,
                  @RequestBody(required = false) Task task) {
        List<Long> toList = new ArrayList<>();
        if (StringUtils.hasText(toLists)) {
            String[] ss = toLists.split(",");
            for (String s : ss) {
                toList.add(Long.parseLong(s));
            }
        }
        if (assignTo != null) {
            toList.add(assignTo);
        }
        if (toList == null || toList.size() == 0) {
            return Result.error(10001, "未指定分配对象。");
        }
        if (toList != null) toList = toList.stream().distinct().collect(Collectors.toList());
        if (toList.size() == 1) {
            Task task0 = issueService.take(issueId, task, toList.get(0));
            return Result.success(task0).set("affect", task0 == null ? 0 : 1).set("now", System.currentTimeMillis());
        } else {
            List<Task> ls = issueService.assign(issueId, task, toList);
            return Result.success(ls).set("affect", ls.size()).set("now", System.currentTimeMillis());
        }

    }

    @PostMapping(value = "/take", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    Result take(@RequestParam(value = "id") Long issueId, @RequestBody(required = false) Task task) {
        Task task0 = issueService.take(issueId, task);
        return Result.success(task0).set("affect", task0 == null ? 0 : 1).set("now", System.currentTimeMillis());

    }

    @PostMapping(value = "/hang")
    @ResponseBody
    Result hang(@RequestParam(value = "id") Long issueId, @RequestParam(value = "hang", required = false) Integer hung, @RequestParam(value = "reason", required = false) String reason) {
        if (hung == null) hung = 1;
        int r = issueService.hang(issueId, hung, reason);
        return Result.success(r).set("affect", r).set("now", System.currentTimeMillis());

    }

    @PostMapping(value = "/urgent")
    @ResponseBody
    Result urgent(@RequestParam(value = "id") Long issueId, @RequestParam(value = "urgent", required = false) Integer urgent, @RequestParam(value = "reason", required = false) String reason) {

        int r = issueService.urgent(issueId, urgent, reason);
        return Result.success(r).set("affect", r).set("now", System.currentTimeMillis());

    }

    @PostMapping(value = "/publish")
    @ResponseBody
    Result publish(@RequestParam(value = "id") Long issueId, @RequestParam(value = "publish", required = false) Integer publish, @RequestParam(value = "assignTo", required = false) Long assignTo) {
        if (publish == null) publish = 1;
        int r = issueService.publish(issueId, publish);
        if (publish == 1 && assignTo != null && assignTo > 0) {
            issueService.take(issueId, null, assignTo);
        }
        return Result.success(r).set("affect", r).set("now", System.currentTimeMillis());

    }

    @PostMapping(value = "/commit")
    @ResponseBody
    Result publish(@RequestParam(value = "id") Long issueId, @RequestParam(value = "commit", required = false) Integer commit) {
        int r = issueService.commit(issueId, commit);
        return Result.success(r).set("affect", r).set("now", System.currentTimeMillis());

    }

    @PostMapping(value = "/complete")
    @ResponseBody
    Result complete(@RequestParam(value = "id") Long issueId, @RequestParam(value = "complete", required = false) Integer complete) {
        if (complete == null) complete = 1;
        int r = issueService.complete(issueId, complete);
        return Result.success(r).set("affect", r).set("now", System.currentTimeMillis());
    }

    @PostMapping(value = "/approve")
    @ResponseBody
    Result approve(@RequestParam(value = "id") Long issueId,
                   @RequestParam(value = "approve", required = false) Integer complete,
                   @RequestParam(value = "reason", required = false) String reason) {
        if (complete == null) complete = 1;
        int r = issueService.approve(issueId, complete, reason);
        return Result.success(r).set("affect", r).set("now", System.currentTimeMillis());
    }


    @PostMapping(value = "/delete")
    @ResponseBody
    Result delete(@RequestParam(value = "id") Long issueId, @RequestParam(value = "value", required = false) Integer value) {
        if (value == null) value = 1;
        int r = issueService.delete(issueId, value);
        return Result.success(r).set("affect", r).set("now", System.currentTimeMillis());
    }

    @PostMapping(value = "/search")
    @ResponseBody
    Result search(@RequestParam(value = "keyword") String keyword) {
        return issueService.search(keyword);
    }

    @PostMapping(value = "/index")
    @ResponseBody
    Result index() {
        return Result.success(issueService.index());
    }


    @PostMapping(value = "/workload")
    @ResponseBody
    Result approve(@RequestParam(value = "date", required = false) Long date,
                   @RequestParam(value = "ownerId", required = false) Long ownerId,
                   @RequestParam(value = "type", required = false) Integer type) {
        int r = issueService.workload(ownerId, date, type);
        return Result.success(r).set("affect", r).set("now", System.currentTimeMillis());
    }

    @PostMapping(value = "/deadline/hung")
    @ResponseBody
    Result deadline() {
        int r = issueService.hungIfTimeout();
        return Result.success(r).set("affect", r).set("now", System.currentTimeMillis());
    }

    @PostMapping(value = "/summary/v40529", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    Result summaryV40529(@RequestBody(required = false) IssueSelector selector) {
        Result result = Result.success();

        result.setData(issueService.summaryAdv(selector));

        return result.set("now", System.currentTimeMillis());
    }

}
